﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SiemensOPC;
using VswService_V7.Config;
using Opc.Ua;
using Opc.Ua.Client;
using System.Windows;
using System.Reflection;
using VswService_V7.OPC.DB;
using VswService_V7.Utility;

namespace VswService_V7.OPC
{
    public class OpcDataFactory
    {

        #region private property
        private SimaticOPCClient opcClient;
        private OPCServer opcConfig;
        private NodeConfig opcNodes;
        #endregion

        #region status
        public bool IsConnected
        {
            get;
            private set;
        }
        #endregion


        public OpcDataFactory(OPCServer config, NodeConfig nodes)
        {
            // Create client API server object
            opcClient = new SimaticOPCClient();
            opcConfig = config;
            opcNodes = nodes;
            IsConnected = false;

           // millConfiger = mill.ToConfigList();

        }

        #region connect & disconnect
        public void Connect()
        {
            // Attach to certificate event
            opcClient.CertificateValidationNotification += new CertificateValidationEventHandler(M_Server_CertificateEvent);
            IsConnected = opcClient.QuickConnect(opcConfig.OpcConnectionDir, 7);
        }

        public void Disconnect()
        {
            opcClient.Disconnect();
            IsConnected = false;
            //clear list
        }
		#endregion


		public HeartBeatCheckAddressDbData heartBeatCheckDbData;

		#region 1+U01
		public StripLoadAddressDbData stripLoadDbData;
		public ACCStripAddressDbdata accStripDbData;
		public StripUnloadAddressDbData stripUnloadDbData;

		#endregion

		#region 2+u01

		public StripInfoAddressDbData StripInfoAddressDbData;
		public RecipeEventAddressDbData RecipeEventAddressDbData;
		public ProcessParameterDbData ProcessParameterDbData;
		public DownTimeAddressDbData DownTimeAddressDbData;

		#endregion

		#region 5+u01

		public FcoAddressDbData FcoAddressDbData;
		public FCOBladeAddressDbData FCOBladeAddressDbData;

		#endregion

		#region 7+u01
		public Fn1PipeEventAddressDbData Fn1PipeEventAddressDbData;
        public Bc1AddressDbdata bc1AddressDbdata;
        public Bc2AddressDbdata bc2AddressDbdata;
        public Sc1AddressDbdata sc1AddressDbdata;
        public Sc2AddressDbdata sc2AddressDbdata;
        public Sc3AddressDbdata sc3AddressDbdata;
        public MustAddressDbData mustAddressDbData;
        public PlsAddressDbData PlsAddressDbData;
        public Is1AddressDbdata Is1AddressDbdata;
        public Is2AddressDbdata Is2AddressDbdata;
        //public Is
        #endregion

        #region 7+u03

        public Is3AddressDbdata Is3AddressDbdata;

        public Fn3PipeEventAddressDbData Fn3PipeEventAddressDbData;

        public Bc4AddressDbdata bc4AddressDbdata;
		public Bc5AddressDbdata bc5AddressDbdata;
		
		public Sc4AddressDbdata sc4AddressDbdata;
		public Sc5AddressDbdata sc5AddressDbdata;

        public OS1AddressDbdata OS1AddressDbdata;
        public OS2AddressDbdata OS2AddressDbdata;

        public VS1AddressDbData VS1AddressDbData;
        public VS2AddressDbData VS2AddressDbData;

        public FltAddressDbData FltAddressDbData;       

        public SampleAddressDbData sampleAddressDbData;
        public SMPBladeAddressDbData SMPBladeAddressDbData;

        public QCAddressDbdata QCAddressDbdata;
        #endregion

        
        public void CreateSubscriptions()
		{
			try
			{
				#region heartBeat
				heartBeatCheckDbData = new HeartBeatCheckAddressDbData(opcClient, opcNodes);
				heartBeatCheckDbData.CreateSubscription();

				#endregion

				#region 1+U01

				stripLoadDbData = new StripLoadAddressDbData(opcClient, opcNodes);
				stripLoadDbData.CreateSubscription();

				stripUnloadDbData = new StripUnloadAddressDbData(opcClient, opcNodes);
				stripUnloadDbData.CreateSubscription();

				accStripDbData = new ACCStripAddressDbdata(opcClient, opcNodes);
				accStripDbData.CreateSubscription();

                #endregion

                #region 2+u02

                StripInfoAddressDbData = new StripInfoAddressDbData(opcClient, opcNodes);
                StripInfoAddressDbData.CreateSubscription();

                ProcessParameterDbData = new ProcessParameterDbData(opcClient, opcNodes);
                ProcessParameterDbData.CreateSubscription();


                RecipeEventAddressDbData = new RecipeEventAddressDbData(opcClient, opcNodes);
                RecipeEventAddressDbData.MachineStatusChanged += MillLineStatusChanged;
                RecipeEventAddressDbData.CreateSubscription();


                //downTime 要比 process data 晚创建，否则可能会漏掉设备状态时间更新
                DownTimeAddressDbData = new DownTimeAddressDbData(opcClient, opcNodes);
                DownTimeAddressDbData.MachineStatusChanged += MillLineStatusChanged;
                DownTimeAddressDbData.CreateSubscription();

                #endregion

                #region  5+u01

                FcoAddressDbData = new FcoAddressDbData(opcClient, opcNodes);
                FcoAddressDbData.CreateSubscription();

                FCOBladeAddressDbData = new FCOBladeAddressDbData(opcClient, opcNodes);
                FCOBladeAddressDbData.CreateSubscription();

                #endregion

                #region 7+u01

                Fn1PipeEventAddressDbData = new Fn1PipeEventAddressDbData(opcClient, opcNodes);
                Fn1PipeEventAddressDbData.CreateSubscription();

                bc1AddressDbdata = new Bc1AddressDbdata(opcClient, opcNodes);
                bc1AddressDbdata.CreateSubscription();

                bc2AddressDbdata = new Bc2AddressDbdata(opcClient, opcNodes);
                bc2AddressDbdata.CreateSubscription();


                sc1AddressDbdata = new Sc1AddressDbdata(opcClient, opcNodes);
                sc1AddressDbdata.CreateSubscription();

                sc2AddressDbdata = new Sc2AddressDbdata(opcClient, opcNodes);
                sc2AddressDbdata.CreateSubscription();

                sc3AddressDbdata = new Sc3AddressDbdata(opcClient, opcNodes);
                sc3AddressDbdata.CreateSubscription();

                mustAddressDbData = new MustAddressDbData(opcClient, opcNodes);
                mustAddressDbData.CreateSubscription();

                PlsAddressDbData = new PlsAddressDbData(opcClient, opcNodes);
                PlsAddressDbData.CreateSubscription();

                Is1AddressDbdata =new Is1AddressDbdata(opcClient, opcNodes);
                Is1AddressDbdata.CreateSubscription();

                Is2AddressDbdata = new Is2AddressDbdata(opcClient, opcNodes);
                Is2AddressDbdata.CreateSubscription();
                #endregion

                #region 7+u03

                //Is3AddressDbdata = new Is3AddressDbdata(opcClient, opcNodes);

                Fn3PipeEventAddressDbData = new Fn3PipeEventAddressDbData(opcClient, opcNodes);
                Fn3PipeEventAddressDbData.CreateSubscription();

                bc4AddressDbdata = new Bc4AddressDbdata(opcClient, opcNodes);
                bc4AddressDbdata.CreateSubscription();

                bc5AddressDbdata = new Bc5AddressDbdata(opcClient, opcNodes);
                bc5AddressDbdata.CreateSubscription();

                sc4AddressDbdata = new Sc4AddressDbdata(opcClient, opcNodes);
                sc4AddressDbdata.CreateSubscription();

                sc5AddressDbdata = new Sc5AddressDbdata(opcClient, opcNodes);
                sc5AddressDbdata.CreateSubscription();

                OS1AddressDbdata = new OS1AddressDbdata(opcClient, opcNodes);
                OS1AddressDbdata.CreateSubscription();

                ////not use
                ////OS2AddressDbdata = new OS2AddressDbdata(opcClient, opcNodes);
                ////OS2AddressDbdata.CreateSubscription();

                VS1AddressDbData = new VS1AddressDbData(opcClient, opcNodes);
                VS1AddressDbData.CreateSubscription();

                ////not use
                ////VS2AddressDbData = new VS2AddressDbData(opcClient, opcNodes);
                ////VS2AddressDbData.CreateSubscription();

                FltAddressDbData = new FltAddressDbData(opcClient, opcNodes);
                FltAddressDbData.CreateSubscription();

                sampleAddressDbData = new SampleAddressDbData(opcClient, opcNodes);
                sampleAddressDbData.CreateSubscription();

                SMPBladeAddressDbData = new SMPBladeAddressDbData(opcClient, opcNodes);
                SMPBladeAddressDbData.CreateSubscription();

                //QCAddressDbdata = new QCAddressDbdata(opcClient, opcNodes);
                //QCAddressDbdata.CreateSubscription();

                #endregion
            }
			catch (Exception ex)
			{
                LogHelper.WriteLog("OpcDataFactory CreateSubscriptions", ex);
				throw ex;
			}
		}


		/// <summary>
		/// Notify ProcessParameterDbData when the device status changes Start / stop Record process data
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void MillLineStatusChanged(object sender, MachineStatusChangedEventArgs e)
        {
            if (ProcessParameterDbData!=null)
                ProcessParameterDbData.MillLineNormal = e.Status;
        }

        #region event handler
        private void M_Server_CertificateEvent(CertificateValidator validator, CertificateValidationEventArgs e)
		{

			MessageBoxResult r = MessageBox.Show("Do you want to accept the untrusted server certificate: \n" +
			   "\nSubject Name: " + e.Certificate.SubjectName.Name +
			   "\nIssuer Name: " + e.Certificate.IssuerName.Name,
			   "Untrusted Server Certificate",
			   MessageBoxButton.OKCancel, MessageBoxImage.Information);
			if (r == MessageBoxResult.OK)
			{
				e.Accept = true;
			}
			else
			{
				e.Accept = false;
			}
		}

		#endregion
	}
    
}
